import dark from '../style/theme/dark';
import light from '../style/theme/light';
import { localForage } from '../localforage';
import { addRootVariable } from '../utils/theme';
import { theme as antDesignTheme } from 'ant-design-vue';
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';

const WINDOW_THEME = '(prefers-color-scheme:dark)';
/**
 * Ant Design 主题 hook
 * 这个方法主要用于 ts vue 中，但是由于相关的主题变量已经同步设置到 :root 上，因此在 css 中可直接使用 var 会更加简单，但是还是保留该文件哈
 * 这里还需要处理 system 的场景，需要添加 window 的 matchMedia 事件处理
 */
export const useTheme = () => {
	let callback: null | ((t: string) => void) = null;

	// 主要导出 token
	const { token } = antDesignTheme.useToken();

	// 向外提供两种可用的 theme : light dark
	const theme = ref('light');

	// 记录当前的主题 - 包含 light dark system 三种主题，但是页面只识别 light dark 因此需要进行处理
	const themeMode = ref('light');

	// 直接提供 configProvideTheme
	const configProvideTheme = computed(() =>
		theme.value === 'light' ? light : dark
	);

	// 需要监听 themeMode 变化 将 system 转换成可用的 light dark
	watch(
		() => themeMode.value,
		newValue => {
			// 如果 themeMode 为 system 则需要先初始化 window 的主题
			if (newValue === 'system') {
				const isDark = window.matchMedia(WINDOW_THEME).matches;
				isDark ? (theme.value = 'dark') : (theme.value = 'light');
			} else theme.value = newValue;

			callback && callback(theme.value);
		}
	);

	/**
	 * 监听主题变化 - utils setTheme 触发的事件
	 * @param { CustomEvent } e chuang-theme-change 事件 设定的参数为 light | dark | system
	 */
	function themeChangeHandler(e: Event) {
		themeMode.value = (<CustomEvent>e).detail.theme;
	}

	// 提供显示监听器
	const themeChange = (c: (theme: string) => void) => (callback = c);

	// 系统级主题切换
	function matchMediaHandler(e: MediaQueryListEvent) {
		const isDark = e.matches;
		if (isDark) {
			theme.value = 'dark';
		} else {
			theme.value = 'light';
		}
		addRootVariable(theme.value);
	}

	// 需要监听 document theme-change 事件
	onMounted(() => {
		// 从 localforage 初始化 theme
		themeMode.value = localForage.getItem('theme') || 'light';

		document.addEventListener('theme-change', themeChangeHandler);

		// 监听 window 系统主题
		window
			.matchMedia(WINDOW_THEME)
			.addEventListener('change', matchMediaHandler);
	});

	// 离开卸载事件
	onUnmounted(() => {
		document.removeEventListener('theme-change', themeChangeHandler);
		window
			.matchMedia(WINDOW_THEME)
			.removeEventListener('change', matchMediaHandler);
	});

	return { token, theme, configProvideTheme, themeMode, themeChange };
};
